package com.koron.ticket.line.work.powerlinesecond.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.bean.workflow.RedirectQuery;
import com.koron.common.core.business.system.SystemCacheUtil;
import com.koron.ticket.feign.TicketChangeStatusFeign;
import com.koron.ticket.feign.bean.defectDispatch.DispatchVO;
import com.koron.ticket.feign.bean.defectDispatch.OrderDispatchWorker;
import com.koron.ticket.line.work.common.bean.FifteenTables;
import com.koron.ticket.line.work.common.bean.FourteenTables;
import com.koron.ticket.line.work.common.bean.Print;
import com.koron.ticket.line.work.common.bean.SixteenTables;
import com.koron.ticket.line.work.common.service.FifteenTablesService;
import com.koron.ticket.line.work.common.service.FourteenTablesService;
import com.koron.ticket.line.work.common.service.OrderChangeStatusService;
import com.koron.ticket.line.work.common.service.SixteenTablesService;
import com.koron.ticket.line.work.enums.TicketNodeStatus;
import com.koron.ticket.line.work.enums.TicketStatus;
import com.koron.ticket.line.work.enums.TicketType;
import com.koron.ticket.line.work.enums.WorkFlowType;
import com.koron.ticket.line.work.workticket.bean.WorkTicket;
import com.koron.ticket.line.work.workticket.bean.WorkTicketQuery;
import com.koron.ticket.line.work.workticket.bean.po.LineTicketOrder;
import com.koron.ticket.line.work.workticket.service.LineTicketOrderService;
import com.koron.ticket.line.work.workticket.service.WorkTicketService;
import com.koron.ticket.work.workPermit.service.WorkPermitService;
import com.koron.ticket.work.workdescription.bean.WorkDescription;
import com.koron.ticket.work.workdescription.service.WorkDescriptionService;
import com.koron.ticket.work.workend.bean.WorkEnd;
import com.koron.ticket.work.workend.bean.WorkEndQuery;
import com.koron.ticket.work.workend.service.WorkEndService;
import com.koron.ticket.work.workflow.bean.WorkFlow;
import com.koron.ticket.work.workflow.bean.WorkFlowQuery;
import com.koron.ticket.work.workflow.service.WorkFlowService;
import com.koron.ticket.work.workinfo.bean.WorkInfo;
import com.koron.ticket.work.workinfo.bean.WorkInfoQuery;
import com.koron.ticket.work.workinfo.service.WorkInfoService;
import com.koron.ticket.work.worklocation.service.WorkLocationService;
import com.koron.ticket.work.workmember.bean.WorkMember;
import com.koron.ticket.work.workmember.bean.WorkMemberQuery;
import com.koron.ticket.work.workmember.service.WorkMemberService;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service("linePowerLineSecondservice")
public class PowerLineSecondservice {

    @Autowired
    private FourteenTablesService lineFourteenTablesService;

    @Autowired
    private WorkFlowService workFlowService;

    @Autowired
    private FifteenTablesService lineFifteenTablesService;

    @Autowired
    private SixteenTablesService lineSixteenTablesService;

    @Autowired
    private WorkTicketService lineWorkTicketService;

    @Autowired
    private WorkInfoService workInfoService;

    @Autowired
    private WorkMemberService workMemberService;

    @Autowired
    private WorkLocationService worklocationservice;

    @Autowired
    private WorkDescriptionService workDescriptionService;

    @Autowired
    private WorkEndService workEndService;

    @Autowired
    private WorkPermitService workPermitService;

    // 变更工单状态
    @Autowired
    private OrderChangeStatusService lineOrderChangeStatusService;

    @Autowired
    private LineTicketOrderService lineTicketOrderService;

    @Autowired
    private TicketChangeStatusFeign ticketChangeStatusFeign;

    /**
     * 保存数据
     * 1. id为空是新增
     * 2. id不为空是更新
     *
     * @param factory
     * @param fourteenTables
     * @return Response对象
     * @version 1.0
     * @see Response
     * @see FifteenTables
     */
    @TaskAnnotation("writeSave")
    public Response writeSave(SessionFactory factory, FourteenTables fourteenTables) {
        // 1. 保存基本数据，并返回工作票id
        String workTicketId = lineFourteenTablesService.writeSave(factory, fourteenTables);

        // 3. 保存工单信息
        List<LineTicketOrder> lineTicketOrderList = fourteenTables.getLineTicketOrderList();
        lineTicketOrderList.forEach(e -> e.setWorkTicketId(workTicketId));
        lineTicketOrderService.removeByTicketId(factory, workTicketId);
        lineTicketOrderService.saveBatch(factory, lineTicketOrderList);
        return Response.success(workTicketId);
    }

    @TaskAnnotation("getPrintData")
    public List<Print> getPrintData(SessionFactory factory, String id) {
        List<Print> result = new ArrayList<>();
        Print print = new Print();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        WorkTicketQuery workTicketQuery = new WorkTicketQuery();
        workTicketQuery.setId(id);
        WorkTicket workTicket = lineWorkTicketService.getSingle(factory, workTicketQuery);
        Integer status = workTicket.getStatus();

        WorkInfoQuery workInfoQuery = new WorkInfoQuery();
        workInfoQuery.setWorkTicketId(id);
        WorkInfo workInfo = workInfoService.getSingle(factory, workInfoQuery);

        WorkMemberQuery workMemberQuery = new WorkMemberQuery();
        workMemberQuery.setWorkTicketId(id);
        List<WorkMember> workMemberList = workMemberService.getList(factory, workMemberQuery);
        String workMemberListString = "";
        if (workMemberList.size() > 0) {
            workMemberListString = workMemberList.stream().map(WorkMember::getMemberName).collect(Collectors.joining(","));
        }

        WorkFlowQuery workFlowQuery = new WorkFlowQuery();
        workFlowQuery.setWorkTicketId(id);
        List<WorkFlow> workFlowList = workFlowService.getList(factory, workFlowQuery);

        WorkEndQuery workEndQuery = new WorkEndQuery();
        workEndQuery.setWorkTicketId(id);
        List<WorkEnd> workEndList = workEndService.getList(factory, workEndQuery);

        // 1. 编号
        print.setCode(workTicket.getCode());
        // 2. 工作地点
        /*List<WorkLocationBean> worklocationlist = worklocationservice.getList(factory, id);
        String worklocationlistStr = "";
        if (worklocationlist.size() > 0) {
            worklocationlistStr = worklocationlist.stream().map(WorkLocationBean::getLocationName).collect(Collectors.joining(","));
        }*/
        // print.setLocationName(worklocationlistStr);
        print.setLocationName(workTicket.getLocationName());
        // 3. 工作负责人名称
        print.setDirectorName(workTicket.getDirectorName());
        // 4. 电话
        print.setPhone(workInfo.getPhone());
        // 5. 工作班组成员
        print.setMemberNameListString(workMemberListString);
        // 6. 总人数
        print.setNumber(workTicket.getNumber());
        // 7. 设备名称
        print.setEquipmentName(workInfo.getEquipmentName());
        // 8. 工作范围
        print.setWorkRange(workInfo.getWorkRange());
        // 9. 工作内容
        print.setContent(workTicket.getContent());
        // 10. 计划开始时间
        if (workTicket.getEstimatedStartTime() != null) {
            // 兼容计划开始时间为空的情况
            print.setEstimatedStartTime(DateUtil.format(workTicket.getEstimatedStartTime(), "yyyy年MM月dd日 HH时mm分"));
        }
        // 11. 计划结束时间
        if (workTicket.getEstimatedEndTime() != null) {
            // 兼容计划结束时间为空的情况
            print.setEstimatedEndTime(DateUtil.format(workTicket.getEstimatedEndTime(), "yyyy年MM月dd日 HH时mm分"));
        }
        // 12. 安全措施
        print.setSafetyMeasures(workInfo.getSafetyMeasures());
        // 13. 工作票签发人
        if (status >= TicketStatus.SIGN.getStatus()) {
            for (WorkFlow workFlow : workFlowList) {
                if (workFlow.getStatus().equals(TicketStatus.SIGN.getStatus())) {
                    print.setSignName(workFlow.getName());
                }
                if (status >= TicketStatus.ACCEPT.getStatus() && workFlow.getStatus().equals(TicketStatus.ACCEPT.getStatus())) {
                    // 工作开始时间
                    print.setSignTime(DateUtil.format(workFlow.getOperationTime(), "yyyy年MM月dd日 HH时mm分"));
                }
                if (status >= TicketStatus.TICKET_END.getStatus() && workFlow.getStatus().equals(TicketStatus.TICKET_END.getStatus()) && "name0".equals(workFlow.getType())) {
                    // 工作结束时间
                    print.setAcceptTime(DateUtil.format(workFlow.getOperationTime(), "yyyy年MM月dd日 HH时mm分"));
                    // 工作终结信息-工作负责人
                    print.setDirectorNameForWorkEnd(workFlow.getName());
                }
            }
        }
        // 14. 备注
        // 14.1 先将work_description表中的所有数据拼接到一起（用户会将工作票变更的信息放在这边）
        List<WorkDescription> workDescriptionList = (ArrayList) workDescriptionService.getListByWorkTicketId(factory, id).getData();
        String description = "";
        if (workDescriptionList != null && workDescriptionList.size() > 0) {
            for (int i = 1; i < workDescriptionList.size() + 1; i++) {
                description += i + "、 " + workDescriptionList.get(i - 1).getContext() + "\n";
            }
        }
        // 14.2 工作票待终结需要拼接待终结的备注
        if (status >= TicketStatus.TICKET_END.getStatus()) {
            for (WorkEnd workEnd : workEndList) {
                if (workEnd.getStatus().equals(TicketStatus.TICKET_END.getStatus())) {
                    description += workEnd.getEndDescription();
                    print.setDescription(description);
                    break;
                }
            }
        } // 14.3 其他时候仅用work_description表中的数据即可
        else {
            print.setDescription(description);
        }
        result.add(print);
        return result;
    }

    @TaskAnnotation("writeSubmit")
    public Response writeSubmit(SessionFactory factory, FourteenTables fourteenTables) {
        String workTicketId = lineFourteenTablesService.writeSubmitByWorkFlowTypeAndStatus(factory, fourteenTables,
                WorkFlowType.LineSecond.getWorkFlow(), TicketStatus.SIGN.getStatus());
        return Response.success(workTicketId);
    }

    @TaskAnnotation("signSave")
    public Response signSave(SessionFactory factory, WorkFlow workFlow) {
        lineWorkTicketService.checkTimeOut(factory, workFlow.getWorkTicketId(), workFlow.getUpdateTime());//检查信息是否过期
        workFlowService.save(factory, workFlow);
        return Response.success("提交/保存成功");
    }

    @TaskAnnotation("acceptSave")
    public Response acceptSave(SessionFactory factory, WorkFlow workFlow) {
        lineWorkTicketService.checkTimeOut(factory, workFlow.getWorkTicketId(), workFlow.getUpdateTime());//检查信息是否过期
        workFlowService.save(factory, workFlow);
        return Response.success("提交/保存成功");
    }

    @TaskAnnotation("workEndSave")
    public Response workEndSave(SessionFactory factory, WorkEnd workEnd) {
        lineFifteenTablesService.endSaveWithStatus(factory, workEnd, TicketStatus.WORK_END.getStatus());
        return Response.success("工作待终结-提交/保存成功");
    }

    @TaskAnnotation("ticketEndSave")
    public Response ticketEndSave(SessionFactory factory, WorkEnd workEnd) {
        lineFifteenTablesService.endSaveWithStatus(factory, workEnd, TicketStatus.TICKET_END.getStatus());
        return Response.success("工作票待终结-提交/保存成功");
    }

    @TaskAnnotation("workflowUpdate")
    public Response workflowUpdate(SessionFactory factory, RedirectQuery redirectQuery) throws ParseException {
        Integer operation = redirectQuery.getOperation();
        String workTicketId = redirectQuery.getDataId();
        WorkTicketQuery workTicketQuery = new WorkTicketQuery();
        workTicketQuery.setId(workTicketId);
        WorkTicket workTicket = lineWorkTicketService.getSingle(factory, workTicketQuery);
        Integer status = workTicket.getStatus();
        String type = workTicket.getType();

        // 1. 如果被驳回，返回对应状态，仅删除签名的数据，其他的数据不做处理
        if (operation == 1) {
            String rejectNodeCode = redirectQuery.getRejectNodeCode();
            rejectNodeCode = rejectNodeCode.replace("call-", "");
            if (rejectNodeCode.equals(TicketNodeStatus.WRITE.getNodeName())) {
                Integer rejectStatus = TicketStatus.WRITE.getStatus();
                lineFifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                workTicket.setStatus(rejectStatus);
            } else if (rejectNodeCode.equals(TicketNodeStatus.SIGN.getNodeName())) {
                Integer rejectStatus = TicketStatus.SIGN.getStatus();
                lineFifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                workTicket.setStatus(rejectStatus);
            } else if (rejectNodeCode.equals(TicketNodeStatus.ACCEPT.getNodeName())) {
                Integer rejectStatus = TicketStatus.ACCEPT.getStatus();
                lineFifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                workTicket.setStatus(rejectStatus);
            } else if (rejectNodeCode.equals(TicketNodeStatus.WORK_END.getNodeName())) {
                Integer rejectStatus = TicketStatus.WORK_END.getStatus();
                lineFifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
                workTicket.setStatus(rejectStatus);
            }
            lineWorkTicketService.update(factory, workTicket);
        } // 2. 如果通过，工作票进入下一个状态，并根据状态的不同进行不同的操作
        else if (operation == 32) {
            String formVariables = redirectQuery.getFormVariables();
            // 2.1 如果是签发状态，1.保存签名信息；2.设置工作票号；3.跳过会签阶段
            if (status.equals(TicketStatus.SIGN.getStatus())) {
                // 保存签名数据
                lineFifteenTablesService.saveWorkFLow(factory, formVariables);
                // 设置工作票号
                if (StrUtil.isBlank(workTicket.getCode())) {
                    String code = lineFifteenTablesService.getLastCodeByUnitAndTicketTypeNew(factory, workTicket.getUnit(), type);
                    workTicket.setCode(code);
                }
                // 跳过会签阶段
                status = status + 1;
            } // 2.3 如果是待接收状态：1.保存签名信息；2.跳过许可阶段
            else if (status.equals(TicketStatus.ACCEPT.getStatus())) {
                // 保存签名信息
                lineFifteenTablesService.saveWorkFLow(factory, formVariables);
                // 跳过许可阶段
                status = status + 1;
                List<LineTicketOrder> lineTicketOrders = lineTicketOrderService.listByTicketId(factory, workTicket.getId());
                // 许可后变更工单状态为执行中
                EamUser redisUser = SystemCacheUtil.getRedisUser(workTicket.getDirector());
                List<WorkMember> workMembers = workMemberService.queryByWorkTicketId(factory, workTicketId);
                for (LineTicketOrder lineTicketOrder : lineTicketOrders) {
                    DispatchVO dispatchVO = new DispatchVO();
                    dispatchVO.setDefectId(lineTicketOrder.getOrderId());
                    dispatchVO.setLocation(workTicket.getLocation());
                    dispatchVO.setLocationName(workTicket.getLocationName());
                    dispatchVO.setNature(0);
                    dispatchVO.setStartTime(workTicket.getEstimatedStartTime());
                    dispatchVO.setEndTime(workTicket.getEstimatedEndTime());
                    dispatchVO.setOrderType("defect");
                    dispatchVO.setLeader(workTicket.getDirector());
                    dispatchVO.setLeaderName(workTicket.getDirectorName());
                    if (redisUser != null && Objects.equals("0", redisUser.getIsOutOrg())) {
                        dispatchVO.setIsOut(0);
                    } else {
                        dispatchVO.setIsOut(1);
                    }
                    dispatchVO.setContext(workTicket.getContent());
                    if (redisUser != null) {
                        dispatchVO.setDeptWork(redisUser.getOrgId());
                        dispatchVO.setDeptWorkName(redisUser.getOrgName());
                    } else {
                        dispatchVO.setDeptWork(workTicket.getDeptId());
                        dispatchVO.setDeptWorkName(workTicket.getDeptName());
                    }
                    List<OrderDispatchWorker> list = new ArrayList<>();
                    dispatchVO.setOrderDispatchWorkerList(list);
                    for (WorkMember workMember : workMembers) {
                        OrderDispatchWorker orderDispatchWorker = new OrderDispatchWorker();
                        orderDispatchWorker.setWorker(workMember.getMemberAccount());
                        orderDispatchWorker.setWorkerName(workMember.getMemberName());
                        orderDispatchWorker.setJobDept(workMember.getMemberUnit());
                        orderDispatchWorker.setJobDeptName(workMember.getMemberUnitName());
                        // orderDispatchWorker.setType();
                        list.add(orderDispatchWorker);
                    }
                    ticketChangeStatusFeign.saveLineDispatchInfo(dispatchVO);
                    // ticketChangeStatusFeign.submitLineDefect(lineTicketOrder.getOrderId(), "IN_EXECUTE");
                }
            }
            // 2.5 如果是工作待终结保存签名信息，以及终结信息(工作票待终结直接调用workflowUpdateEnd接口)
            else if (status.equals(TicketStatus.WORK_END.getStatus())) {
                // 保存终结信息
                WorkEnd workEnd = JSONObject.parseObject(formVariables, WorkEnd.class);
                workEnd.setId(workEnd.getWorkEndId());
                workEndService.saveWithStatus(factory, workEnd, TicketStatus.WORK_END.getStatus());
                // 保存签名信息
                List<WorkFlow> workFlowList = workEnd.getWorkFlowList();
                if (workFlowList != null && workFlowList.size() > 0) {
                    for (WorkFlow workFLow : workFlowList) {
                        workFlowService.save(factory, workFLow);
                    }
                }
                // 归档后，缺陷工单变为“待验收”
                List<LineTicketOrder> lineTicketOrders = lineTicketOrderService.listByTicketId(factory, workTicket.getId());
                for (LineTicketOrder lineTicketOrder : lineTicketOrders) {
                    ticketChangeStatusFeign.submitLineDefect(lineTicketOrder.getOrderId(), "WAIT_ACCEPT");
                }
            }
            // 3. 状态更新，更新主票
            workTicket.setStatus(status + 1);
            lineWorkTicketService.update(factory, workTicket);
        } else if (operation == 256) {
            Integer rejectStatus = TicketStatus.WRITE.getStatus();
            lineFifteenTablesService.clenWorkFlowByStatus(factory, workTicketId, rejectStatus);
            workTicket.setStatus(rejectStatus);
            lineWorkTicketService.update(factory, workTicket);
        } else {
            return Response.fail("操作类型为：" + operation + ",请联系运维人员");
        }

        return Response.success("电气第一种工作票提交成功");
    }

    @TaskAnnotation("workflowUpdateEnd")
    public Response workflowUpdateEnd(SessionFactory factory, RedirectQuery redirectQuery) throws ParseException {
        lineFifteenTablesService.workflowUpdateEnd(factory, redirectQuery);
        return Response.success("工作票已归档");
    }

    @TaskAnnotation("workflowUpdateCancel")
    public Response workflowUpdateCancel(SessionFactory factory, RedirectQuery redirectQuery) {
        lineFifteenTablesService.workflowUpdateCancel(factory, redirectQuery);
        return Response.success("工作票已作废");
    }

    public SixteenTables add() {
        SixteenTables sixteenTables = lineSixteenTablesService.addByType(TicketType.LineSecond.getType());
        return sixteenTables;
    }

    public void deleteById(SessionFactory factory, String id) {
        lineFourteenTablesService.deleteById(factory, id);
    }

    public FourteenTables getById(SessionFactory factory, String id) {
        FourteenTables fourteenTables = lineFourteenTablesService.getById(factory, id);
        // 查询工单信息
        List<LineTicketOrder> lineTicketOrders = lineTicketOrderService.listByTicketId(factory, id);
        fourteenTables.setLineTicketOrderList(lineTicketOrders);
        return fourteenTables;
    }
}
